package com.handa.common.security;

import cn.hutool.core.util.IdUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.handa.common.entity.LoginUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Service
public class MyTokenService {

    private final Long expiration = 36000000L;

    @Value("${spring.security.token.header:}")
    private String header;

    @Value("${spring.security.token.secret:}")
    private String secret;


    public LoginUser parseToken(HttpServletRequest request) {
        String jwt = getJwt(request);
        if (jwt != null) {
            return parseJwt(jwt);
        }
        return null;
    }

    private String getJwt(HttpServletRequest request) {
        String jwt = request.getHeader(header);
        if (StringUtils.isBlank(jwt)) {
            return null;
        }
        if (jwt.startsWith("Bearer ")) {
            jwt = jwt.replace("Bearer ", "");
        }
        return jwt;
    }

    public LoginUser parseJwt(String jwtToken) {
        LoginUser loginUser = new LoginUser();

        try {
            DecodedJWT jwt = JWT.decode(jwtToken);
            loginUser.setJwt(jwtToken);
            loginUser.setUsername(jwt.getClaim("User.name").asString());
            loginUser.setTokenId(jwt.getClaim("Token.id").asString());
            loginUser.setRoleId(jwt.getClaim("Role.id").asInt());
            loginUser.setUserId(jwt.getClaim("User.id").asLong());
            loginUser.setNickname(jwt.getClaim("User.nickname").asString());
            return loginUser;
        } catch (JWTDecodeException var4) {
            return null;
        }
    }

    public String newToken(LoginUser loginUser) {
        loginUser.setTokenId(IdUtil.randomUUID());
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + this.expiration);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        return JWT.create().withClaim("User.name", loginUser.getUsername())
                .withClaim("User.nickname", loginUser.getNickname())
                .withClaim("User.id", loginUser.getUserId())
                .withClaim("Token.id", loginUser.getTokenId())
                .withClaim("Role.id", loginUser.getRoleId())
                .withIssuedAt(now).withExpiresAt(expiryDate).sign(algorithm);
    }

}
